// server.js
const express = require('express');
const { JSDOM } = require('jsdom');
const { SVG, registerWindow } = require('@svgdotjs/svg.js');
const fs = require('fs').promises;
const path = require('path');

const app = express();
const port = 3000;

// 设置 DOM 环境（SVG.js 需要 DOM 环境）
function setupDOM() {
    const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');
    global.window = dom.window;
    global.document = dom.window.document;
}

// 初始化 DOM
setupDOM();

registerWindow(window, document);

// 创建保存 SVG 文件的目录
const svgDir = path.join(__dirname, 'svg_files');
async function ensureSvgDir() {
    try {
        await fs.access(svgDir);
    } catch {
        await fs.mkdir(svgDir, { recursive: true });
    }
}

// 路由1: 基础 SVG 生成
app.get('/svg', (req, res) => {
    const { width = 400, height = 300, text = 'Hello SVG' } = req.query;

    const draw = SVG().size(parseInt(width), parseInt(height));
    
    // 创建渐变背景
    const gradient = draw.gradient('linear', function(add) {
        add.stop(0, '#667eea');
        add.stop(1, '#764ba2');
    });
    
    draw.rect(width, height).fill(gradient);
    
    // 添加文本
    /*draw.text(text)
        .move(50, 150)
        .font({ 
            size: 24, 
            family: 'Arial',
            anchor: 'start',
            fill: '#fff',
        })
        .move(95 + index * 60, 240 - value);*/

        const textElement = draw.plain(text);
        textElement
        .font({ 
            size: 24, 
            fill: '#fff'
        });

        textElement.attr('x', 50);
        textElement.attr('y', 150);
    
    
    // 添加一个圆形装饰
    draw.circle(80)
        .move(300, 50)
        .fill('rgba(255,255,255,0.2)')
        .stroke({ color: '#fff', width: 2 });
    
    // 设置响应头并返回 SVG
    res.setHeader('Content-Type', 'image/svg+xml');
    res.send(draw.svg());
});

// 路由2: 柱状图 SVG
app.get('/chart', (req, res) => {
    const draw = SVG().size(500, 300);
    
    // 简单的柱状图数据
    const data = [30, 60, 90, 120, 150, 180];
    const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD'];
    
    // 添加背景
    draw.rect(500, 300).fill('#f8f9fa');
    
    // 绘制柱状图
    data.forEach((value, index) => {
        draw.rect(40, value)
            .move(80 + index * 60, 250 - value)
            .fill(colors[index])
            .stroke({ color: '#333', width: 1 });
        
        // 添加数值标签
        /*draw.text(value.toString())
            .move(95 + index * 60, 240 - value)
            .font({ size: 12, family: 'Arial', fill: '#333' });*/

        const textElement = draw.plain(value.toString());
        textElement.font({ size: 12, family: 'Arial', fill: '#333' });

        textElement.attr('x', 95 + index * 60);
        textElement.attr('y', 240 - value);
    });
    
    // 添加标题
    /*draw.text('销售数据图表')
        .move(180, 30)
        .font({ size: 20, family: 'Arial', fill: '#333', weight: 'bold' });*/

        const textElement = draw.plain('销售数据图表');
        textElement
        .font({ size: 20, family: 'Arial', fill: '#333', weight: 'bold' });

        textElement.attr('x', 180);
        textElement.attr('y', 30);
    
    res.setHeader('Content-Type', 'image/svg+xml');
    res.send(draw.svg());
});

// 路由3: 饼图 SVG
app.get('/pie', (req, res) => {
    const draw = SVG().size(400, 300);
    
    // 饼图数据
    const data = [
        { value: 40, color: '#FF6B6B', label: '产品 A' },
        { value: 25, color: '#4ECDC4', label: '产品 B' },
        { value: 20, color: '#45B7D1', label: '产品 C' },
        { value: 15, color: '#96CEB4', label: '产品 D' }
    ];
    
    // 绘制饼图
    let currentAngle = 0;
    const total = data.reduce((sum, item) => sum + item.value, 0);
    const centerX = 150;
    const centerY = 150;
    const radius = 80;
    
    data.forEach((item, index) => {
        const angle = (item.value / total) * 360;
        const endAngle = currentAngle + angle;
        
        // 计算弧线路径
        const startRad = (currentAngle - 90) * Math.PI / 180;
        const endRad = (endAngle - 90) * Math.PI / 180;
        
        const x1 = centerX + radius * Math.cos(startRad);
        const y1 = centerY + radius * Math.sin(startRad);
        const x2 = centerX + radius * Math.cos(endRad);
        const y2 = centerY + radius * Math.sin(endRad);
        
        const largeArc = angle > 180 ? 1 : 0;
        
        const pathData = [
            `M ${centerX} ${centerY}`,
            `L ${x1} ${y1}`,
            `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`,
            'Z'
        ].join(' ');
        
        draw.path(pathData).fill(item.color).stroke({ color: '#fff', width: 2 });
        
        currentAngle = endAngle;
    });
    
    // 添加图例
    data.forEach((item, index) => {
        // 图例颜色块
        draw.rect(15, 15)
            .move(250, 80 + index * 25)
            .fill(item.color);
        
        // 图例文本
        /*draw.text(`${item.label}: ${item.value}%`)
            .move(270, 92 + index * 25)
            .font({ size: 12, family: 'Arial', fill: '#333' });*/

        const textElement = draw.plain(`${item.label}: ${item.value}%`);
        textElement
        .font({ size: 12, family: 'Arial', fill: '#333' });

        textElement.attr('x', 270);
        textElement.attr('y', 92 + index * 25);    
    });
    
    res.setHeader('Content-Type', 'image/svg+xml');
    res.send(draw.svg());
});

// 新路由4: 保存 SVG 到文件
app.get('/save-svg', async (req, res) => {
    try {
        await ensureSvgDir();
        
        const { type = 'basic', filename } = req.query;
        let svgContent = '';
        
        // 根据类型生成不同的 SVG
        switch(type) {
            case 'chart':
                const chartDraw = SVG().size(500, 300);
                const data = [30, 60, 90, 120, 150, 180];
                const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD'];
                
                chartDraw.rect(500, 300).fill('#f8f9fa');
                data.forEach((value, index) => {
                    chartDraw.rect(40, value)
                        .move(80 + index * 60, 250 - value)
                        .fill(colors[index])
                        .stroke({ color: '#333', width: 1 });
                });
                svgContent = chartDraw.svg();
                break;
                
            case 'pie':
                const pieDraw = SVG().size(400, 300);
                const pieData = [
                    { value: 40, color: '#FF6B6B' },
                    { value: 25, color: '#4ECDC4' },
                    { value: 20, color: '#45B7D1' },
                    { value: 15, color: '#96CEB4' }
                ];
                
                let pieCurrentAngle = 0;
                const pieTotal = pieData.reduce((sum, item) => sum + item.value, 0);
                const pieCenterX = 150, pieCenterY = 150, pieRadius = 80;
                
                pieData.forEach(item => {
                    const angle = (item.value / pieTotal) * 360;
                    const endAngle = pieCurrentAngle + angle;
                    
                    const startRad = (pieCurrentAngle - 90) * Math.PI / 180;
                    const endRad = (endAngle - 90) * Math.PI / 180;
                    
                    const x1 = pieCenterX + pieRadius * Math.cos(startRad);
                    const y1 = pieCenterY + pieRadius * Math.sin(startRad);
                    const x2 = pieCenterX + pieRadius * Math.cos(endRad);
                    const y2 = pieCenterY + pieRadius * Math.sin(endRad);
                    
                    const largeArc = angle > 180 ? 1 : 0;
                    const pathData = [
                        `M ${pieCenterX} ${pieCenterY}`,
                        `L ${x1} ${y1}`,
                        `A ${pieRadius} ${pieRadius} 0 ${largeArc} 1 ${x2} ${y2}`,
                        'Z'
                    ].join(' ');
                    
                    pieDraw.path(pathData).fill(item.color).stroke({ color: '#fff', width: 2 });
                    pieCurrentAngle = endAngle;
                });
                svgContent = pieDraw.svg();
                break;
                
            default:
                const basicDraw = SVG().size(400, 300);
                const gradient = basicDraw.gradient('linear', function(add) {
                    add.stop(0, '#667eea');
                    add.stop(1, '#764ba2');
                });
                basicDraw.rect(400, 300).fill(gradient);
                basicDraw.circle(80).move(300, 50).fill('rgba(255,255,255,0.2)').stroke({ color: '#fff', width: 2 });
                svgContent = basicDraw.svg();
        }
        
        const filePath = path.join(svgDir, filename || `${type}_${Date.now()}.svg`);
        await fs.writeFile(filePath, svgContent);
        
        res.json({
            success: true,
            message: 'SVG 文件保存成功',
            filename: path.basename(filePath),
            path: filePath,
            url: `/view-svg?file=${path.basename(filePath)}`
        });
        
    } catch (error) {
        res.status(500).json({
            success: false,
            message: '保存 SVG 文件失败',
            error: error.message
        });
    }
});

// 新路由5: 查看已保存的 SVG 文件
app.get('/view-svg', async (req, res) => {
    try {
        const { file } = req.query;
        
        if (!file) {
            // 如果没有指定文件，显示文件列表
            await ensureSvgDir();
            const files = await fs.readdir(svgDir);
            const svgFiles = files.filter(f => f.endsWith('.svg'));
            
            let html = `
                <!DOCTYPE html>
                <html>
                <head>
                    <title>SVG 文件列表</title>
                    <style>
                        body { font-family: Arial, sans-serif; margin: 40px; }
                        .file-list { list-style: none; padding: 0; }
                        .file-item { margin: 10px 0; padding: 15px; background: #f8f9fa; border-radius: 5px; }
                        .file-link { color: #007bff; text-decoration: none; font-weight: bold; }
                        .file-link:hover { text-decoration: underline; }
                        .back-link { display: inline-block; margin-top: 20px; padding: 10px 15px; background: #6c757d; color: white; text-decoration: none; border-radius: 3px; }
                    </style>
                </head>
                <body>
                    <h1>已保存的 SVG 文件</h1>
                    ${svgFiles.length === 0 ? '<p>暂无保存的 SVG 文件</p>' : '<ul class="file-list">'}
            `;
            
            svgFiles.forEach(svgFile => {
                html += `
                    <li class="file-item">
                        <a class="file-link" href="/view-svg?file=${svgFile}" target="_blank">${svgFile}</a>
                        <br>
                        <small>保存路径: ${path.join(svgDir, svgFile)}</small>
                    </li>
                `;
            });
            
            html += `
                    ${svgFiles.length > 0 ? '</ul>' : ''}
                    <a class="back-link" href="/">返回首页</a>
                </body>
                </html>
            `;
            
            return res.send(html);
        }
        
        // 显示指定的 SVG 文件
        const filePath = path.join(svgDir, file);
        const svgContent = await fs.readFile(filePath, 'utf8');
        
        const html = `
            <!DOCTYPE html>
            <html>
            <head>
                <title>查看 SVG: ${file}</title>
                <style>
                    body { font-family: Arial, sans-serif; margin: 40px; text-align: center; }
                    .svg-container { margin: 20px 0; border: 1px solid #ddd; padding: 20px; border-radius: 5px; background: white; }
                    .back-link { display: inline-block; margin: 10px; padding: 10px 15px; background: #007bff; color: white; text-decoration: none; border-radius: 3px; }
                    .info { background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0; text-align: left; }
                </style>
            </head>
            <body>
                <h1>SVG 文件: ${file}</h1>
                
                <div class="info">
                    <strong>文件信息:</strong><br>
                    文件名: ${file}<br>
                    路径: ${filePath}<br>
                    大小: ${svgContent.length} 字符
                </div>
                
                <div class="svg-container">
                    ${svgContent}
                </div>
                
                <div>
                    <a class="back-link" href="/view-svg">返回文件列表</a>
                    <a class="back-link" href="/">返回首页</a>
                    <a class="back-link" href="/download-svg?file=${file}" download>下载 SVG</a>
                </div>
            </body>
            </html>
        `;
        
        res.send(html);
        
    } catch (error) {
        res.status(500).send(`
            <!DOCTYPE html>
            <html>
            <head><title>错误</title></head>
            <body>
                <h1>读取 SVG 文件失败</h1>
                <p>错误信息: ${error.message}</p>
                <a href="/view-svg">返回文件列表</a>
            </body>
            </html>
        `);
    }
});

// 新路由6: 下载 SVG 文件
app.get('/download-svg', async (req, res) => {
    try {
        const { file } = req.query;
        
        if (!file) {
            return res.status(400).send('请指定要下载的文件');
        }
        
        const filePath = path.join(svgDir, file);
        await fs.access(filePath); // 检查文件是否存在
        
        res.setHeader('Content-Type', 'image/svg+xml');
        res.setHeader('Content-Disposition', `attachment; filename="${file}"`);
        
        const fileStream = require('fs').createReadStream(filePath);
        fileStream.pipe(res);
        
    } catch (error) {
        res.status(404).send('文件未找到');
    }
});

// 路由7: 首页，显示所有可用路由
app.get('/', (req, res) => {
    res.send(`
        <!DOCTYPE html>
        <html>
        <head>
            <title>SVG.js Express 服务器</title>
            <style>
                body { font-family: Arial, sans-serif; margin: 40px; }
                .link { display: block; margin: 10px 0; padding: 10px; background: #f0f0f0; text-decoration: none; color: #333; border-radius: 5px; }
                .link:hover { background: #e0e0e0; }
                .section { margin: 30px 0; }
                .section-title { border-bottom: 2px solid #007bff; padding-bottom: 5px; }
            </style>
        </head>
        <body>
            <h1>SVG.js Express 服务器示例</h1>
            
            <div class="section">
                <h2 class="section-title">SVG 生成示例</h2>
                <a class="link" href="/svg" target="_blank">基础 SVG</a>
                <a class="link" href="/svg?width=600&height=400&text=自定义文本" target="_blank">带参数的基础 SVG</a>
                <a class="link" href="/chart" target="_blank">柱状图</a>
                <a class="link" href="/pie" target="_blank">饼图</a>
            </div>
            
            <div class="section">
                <h2 class="section-title">SVG 文件操作</h2>
                <a class="link" href="/save-svg?type=basic&filename=my_design.svg" target="_blank">保存基础 SVG 到文件</a>
                <a class="link" href="/save-svg?type=chart&filename=my_chart.svg" target="_blank">保存柱状图到文件</a>
                <a class="link" href="/save-svg?type=pie&filename=my_pie.svg" target="_blank">保存饼图到文件</a>
                <a class="link" href="/view-svg" target="_blank">查看已保存的 SVG 文件</a>
            </div>
        </body>
        </html>
    `);
});

// 启动服务器
app.listen(port, async () => {
    await ensureSvgDir();
    console.log(`🚀 SVG 服务器运行在 http://localhost:${port}`);
    console.log(`📊 可用路由:`);
    console.log(`   http://localhost:${port}/ - 首页`);
    console.log(`   http://localhost:${port}/svg - 基础 SVG`);
    console.log(`   http://localhost:${port}/chart - 柱状图`);
    console.log(`   http://localhost:${port}/pie - 饼图`);
    console.log(`   http://localhost:${port}/save-svg - 保存 SVG 到文件`);
    console.log(`   http://localhost:${port}/view-svg - 查看 SVG 文件`);
    console.log(`   http://localhost:${port}/download-svg - 下载 SVG 文件`);
    console.log(`📁 SVG 文件保存目录: ${svgDir}`);
});